package myJs.user.soft.horizontalBoxplot

import myJs.api.Api
import myJs.myPkg.yup.Yup
import myJs.tool.Tool
import myJs.tool.Tool.messages
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._

import scala.collection.mutable
import scala.concurrent.{Future, Promise}
import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.timers.SetTimeoutHandle

/** Created by yz on 9/11/2022
  */
object Schema {

  case class ValidInfo(v: String, valid: Boolean)

  val cacheMap = mutable.SeqMap[String, ValidInfo]()

  def cacheTest(key: String)(f: String => Future[Boolean]) = (v: String) => {
    val beforeV = cacheMap.getOrElse(key, ValidInfo("", true))
    if (beforeV.v != v) {
      f(v).map { x =>
        cacheMap.put(key, ValidInfo(v, x))
        x
      }.toJSPromise
    } else {
      Future {
        beforeV.valid
      }.toJSPromise
    }
  }

  var delayTimer = null: SetTimeoutHandle
  def missionNameValidateF(key: String) = cacheTest(key) { v: String =>
    val promise = Promise[Boolean]()
    import shared.pojo.Pojo.workflowMission._
    val request = MissionNameCheck.Request(id = Tool.getId.toInt, missionName = v)

    def f = Api.mission.nameCheck(request).map { response =>
      response.valid
    }
    js.timers.clearTimeout(delayTimer)
    delayTimer = js.timers.setTimeout(300) {
      f.map { rs =>
        promise.success(rs)
      }
    }
    promise.future
  }

  def fileValidateF(key: String) = cacheTest(key) { v: String =>
    import shared.pojo.Pojo.soft._
    val request = CheckFileName.Request(id = Tool.getId.toInt, fileName = v)
    if (v.nonEmpty) {
      Api.soft.checkFileName(request).map { response =>
        response.valid
      }
    } else {
      Future {
        true
      }
    }

  }

  def transformF = (v: Double) => {
    if (v.isNaN) {
      js.undefined
    } else js.defined(v)
  }

  val schema = Yup
    .`object`()
    .shape(
      js.Dictionary(
        "missionName" -> Yup
          .string()
          .required(messages("null"))
          .test(name = "checkExist", message = messages("exist"), test = missionNameValidateF("missionName")),
        "file" -> Yup
          .string()
          .required(messages("null"))
          .test(name = "checkNotExist", message = s"${messages("notExist")}", test = fileValidateF("file")),
        "groupFile" -> Yup
          .string()
          .required(message = s"${messages("null")}")
          .test(name = "checkNotExist", message = s"${messages("notExist")}", test = fileValidateF("groupFile")),
        "qValueCutoff" -> {
          val min = 0
          val max = 1
          val message = s"必须为${min}-${max}之间的实数!"
          Yup
            .number()
            .min(min, message)
            .max(max, message)
            .typeError(message = s"${message}")
        }
      )
    )

}
